#include"ListNode.h"
#include<assert.h>
#include<stdlib.h>
#include<stdio.h>
SLT* SLTNewNode(IntTypeDef x)
{
	SLT* Node = (SLT*)malloc(sizeof(SLT));
	if (Node == NULL)
	{
		perror("malloc fail:");
		return;
	}
	Node->value = x;
	Node->next = NULL;
	return Node; 
}
void SLTNodePushFront(SLT** pphead,IntTypeDef x)
{
	assert(pphead);
	SLT*Node=SLTNewNode(x);
	if (*pphead == NULL)
	{
		*pphead = Node;
		return;
	}
	Node->next = *pphead;
	*pphead = Node;
}
void SLTNodeDraw(SLT** phead)
{
	assert(phead);
	if (*phead == NULL)
	{
		return;
	}
	SLT* cur = *phead;
	while (cur != NULL)
	{
		printf("%d->", cur->value);
		cur = cur->next;
	}
	printf("NULL\n");
}
void SLTNodePushBack(SLT** pphead, IntTypeDef x)
{
	assert(pphead);
	SLT* Node = SLTNewNode(x);
	if (*pphead == NULL)
	{
		*pphead = Node;
		return;
	}
	SLT* tail = *pphead;
	while (tail->next != NULL)
	{
		tail = tail->next;
	}
	tail->next = Node;
}
int size(SLT** pphead)
{
	assert(pphead);
	SLT* cur = *pphead;
	int count = 0;
	while (cur != NULL)
	{
		count++;
		cur = cur->next;
	}
	return count;
}
void SLTNodeInsertPush(SLT** pphead, IntTypeDef x, int pos)
{
	assert(pphead);
	assert(pos > 0 && pos<size(pphead));
	SLT* tail = *pphead;
	SLT* prev = NULL;
	while (--pos> 0)
	{
		prev = tail;
		tail = tail->next;
	}
	SLT* Node = SLTNewNode(x);
	prev->next = Node;
	Node->next = tail;
}
void SLTNodePopFront(SLT** pphead)
{
	assert(pphead);
	SLT* cur = *pphead;
	*pphead = (*pphead)->next;
	free(cur);
}
void SLTNodePopBack(SLT** pphead)
{

	assert(pphead);
	SLT* prev = *pphead;
	SLT* cur = *pphead;
	while(cur->next!=NULL)
	{
		prev = cur;
		cur = cur->next;
	}
	free(cur);
	prev->next = NULL;
}
void SLTNodePopInsert(SLT** pphead, int pos)
{
	assert(pphead);
	if (pos<0 || pos>size(pphead))
	{
		perror("fail:");
		return;
	}
	SLT* prev = *pphead;
	SLT* cur = *pphead;
	while (pos-- > 0)
	{
		prev = cur;
		cur = cur->next;
	}
	prev->next = cur->next;
	free(cur);
}

ListNodeT* ListNewNode(IntTypeDef x)
{
	
	ListNodeT* Node = (ListNodeT*)malloc(sizeof(ListNodeT));
	if (Node == NULL)
	{
		perror("malloc fail:");
		return;
	}
	Node->prev = NULL;
	Node->next = NULL;
	Node->value = x;
}
ListNodeT* ListNodeInit()
{
	
	ListNodeT* Node = ListNewNode(-1);
	Node->prev = Node;
	Node->next = Node;
	return Node;
}
void ListNodePushBack(ListNodeT* pphead, IntTypeDef x)
{
	assert(pphead);
	ListNodeT* Node = ListNewNode(x);
	//Node->next->prev = NULL;
	ListNodeT* tail = pphead->prev;
	tail->next = Node;
	Node->prev = tail;
	Node->next = pphead;
	pphead->prev = Node;
}
void ListNodeDraw(ListNodeT* pphead, IntTypeDef x)
{
	assert(pphead);
	ListNodeT* cur = pphead->next;
	while (cur != pphead)
	{
		printf("%d<->", cur->value);
		cur = cur->next;
	}
	printf("NULL\n");
}
void ListNodePushFront(ListNodeT* pphead, IntTypeDef x)
{
	assert(pphead);
	ListNodeT* Node = ListNewNode(x);
	ListNodeT* tmp = pphead->next;
	tmp->prev = Node;
	Node->next = pphead->next;
	Node->prev = pphead;
	pphead->next = Node;
}
void ListNodePopBack(ListNodeT* pphead)
{
	assert(pphead);
	ListNodeT* tail = pphead->prev;
	ListNodeT* tailprev = tail->prev;
	free(tail);
	tailprev->next = pphead;
	pphead->prev = tailprev;
}
void ListNodePopFront(ListNodeT* pphead)
{
	assert(pphead);
	ListNodeT* cur = pphead->next;
	ListNodeT* tmp = cur->next;
	pphead->next = tmp;
	tmp->prev = pphead;
	free(cur);
}
ListNodeT* ListNodeFind(ListNodeT* pphead, IntTypeDef x)
{
	assert(pphead);
	ListNodeT* cur = pphead->next;
	while (cur != pphead)
	{
		if (cur->value == x)
		{
			return cur;
		}
		cur = cur->next;
	}
	return NULL;
}
void ListNodePopInsert(ListNodeT* pos)
{
	assert(pos);
	ListNodeT* cur = pos->prev;
	ListNodeT* tmp = pos->next;
	cur->next = tmp;
	tmp->prev = cur;
	free(pos);
}
void ListNodePushInsert(ListNodeT* pos,IntTypeDef x)
{
	assert(pos);
	ListNodeT* cur = pos->prev;
	ListNodeT* Node = ListNewNode(x);
	Node->next = pos;
	pos->prev = Node;
	Node->prev = cur;
	cur->next = Node;
}
SLT* SLTNodeDeleteAll(SLT** pphead,int value)
{
	assert(pphead);
	SLT* prev = NULL;
	SLT* cur = *pphead;
	while (cur != NULL)
	{
		if (cur->value == value)
		{
			if (prev)
			{
				prev->next = cur->next;
				free(cur);
				cur = prev->next;
			}
			else
			{
				cur = (*pphead)->next;
				free(*pphead);
				*pphead = cur;
			}
		}
		else
		{
			prev = cur;
			cur = cur->next;
		}
	}
	return pphead;
}
SLT* SLTNodeReversal(SLT** pphead)
{
	assert(pphead);
	SLT* prev = NULL;
	SLT* cur = *pphead;
	while(cur != NULL)
	{
		SLT* Next = cur->next;
		cur->next = prev;
		prev = cur;
		cur = Next;
	}
	*pphead = prev;
	return pphead;
}
SLT* SLTNodeFindMin(SLT** pphead)
{
	assert(pphead);
	SLT* Min = *pphead;
	SLT* cur = *pphead;
	SLT* prev = *pphead;
	SLT* prevMin = *pphead;
	while (cur != NULL)
	{
		if (Min->value > cur->value)
		{

			Min = cur;
			prevMin = prev;
		}
		prev = cur;
		cur = cur->next;
	}
	prevMin->next = Min->next;
	free(Min);
	return pphead;
}